#include "SysButton.h"

#define SYS_BUTTON_COUNT 18

static SysButton_t g_button[SYS_BUTTON_COUNT];
// static SysButtonHandle_t g_buttonHandle = NULL;

uint8_t SysButtonGetLevel(uint8_t id)
{
    if (id < SYS_BUTTON_COUNT && g_button[id].enable)
    {
        return g_button[id].lastLevel;
    }
    return 0;
}

int SysButtonRegister(uint8_t id, uint8_t io, SysButtonHandle_t handle)
{
    SysButton_t *btn;

    if (id < SYS_BUTTON_COUNT && !g_button[id].enable)
    {
        btn = &g_button[id];
        btn->enable = true;
        btn->flipping = false;
        btn->io = io;
        btn->handle = handle;
        btn->lastLevel = HalGPIOGetLevel(io);
        return id;
    }

    return -1;
}

int SysButtonLongpressSet(uint8_t id, uint8_t level, uint32_t interval)
{
    SysButton_t *btn;

    if (id < SYS_BUTTON_COUNT && g_button[id].enable)
    {
        btn = &g_button[id];
        btn->longpress.enable = true;
        btn->longpress.triggerLevel = level;
        btn->longpress.triggerInterval = interval;
        return id;
    }

    return -1;
}

void SysButtonPoll(void)
{
    uint8_t i;
    uint8_t curLevel;
    SysButton_t *btn;

    for (i = 0; i < SYS_BUTTON_COUNT; i++)
    {
        btn = &g_button[i];
        if (btn->enable)
        {
            curLevel = HalGPIOGetLevel(btn->io);
            if (curLevel != btn->lastLevel)
            {
                if (btn->flipping)
                {
                    if (SysTimeHasPast(btn->jitterTime, 5))
                    {
                        btn->lastLevel = curLevel;
                        btn->flipping = false;
                        if (btn->longpress.enable && curLevel == btn->longpress.triggerLevel)
                        {
                            btn->longpress.lastTriggerTime = SysTime();
                        }
                        if (btn->handle)
                        {
                            btn->handle(SYS_BUTTON_EVENT_LEVEL_FLIP, i, btn->io, curLevel);
                        }
                    }
                }
                else
                {
                    btn->flipping = true;
                    btn->jitterTime = SysTime();
                }
            }
            else
            {
                if (btn->longpress.enable &&
                    curLevel == btn->longpress.triggerLevel &&
                    SysTimeHasPast(btn->longpress.lastTriggerTime, btn->longpress.triggerInterval))
                {
                    if (btn->handle)
                    {
                        btn->handle(SYS_BUTTON_EVENT_LONG_PRESS, i, btn->io, curLevel);
                    }
                    btn->longpress.lastTriggerTime = SysTime();
                }
            }
        }
    }
}

void SysButtonInitialize(void)
{
    memset(g_button, 0, sizeof(SysButton_t) * SYS_BUTTON_COUNT);
}
